#ifndef LIST_HPP
#define LIST_HPP
#include <iostream>
namespace poly {
	template<typename T>
	class list_iterator
	{
		private:
			list_iterator<T> *left, *right, *orig;
			T *data;
		public:
			list_iterator();
			list_iterator(const list_iterator&);
			list_iterator(T data);
			~list_iterator();
			list_iterator& operator++();
			list_iterator& operator++(const int);
			list_iterator& operator--();
			list_iterator& operator--(const int);
			list_iterator& operator+=(const int);
			list_iterator& operator+(const int) const;
			list_iterator& operator-=(const int);
			list_iterator& operator-(const int) const;
			bool operator ==(const list_iterator&) const;
			bool operator !=(const list_iterator&) const;
			T& operator *() const;
			list_iterator& insert_before(const T&);
			list_iterator& original();
		template <class U>
		friend class list;
	};

	template<typename T>
	class list
	{
		public:
			typedef list_iterator<T> iterator;
		private:
			iterator *_begin, *_end;
		public:
			list();
			list(const T &);
			list(const list &);
			list_iterator<T> begin() const;
			list_iterator<T> end() const;
			T& operator[](int) const;
			list<T>& operator =(const list<T> &);
			list_iterator<T> get_iterator(int);
			int size() const;
			list& push_back(const T &);
			void clear();
			void reverse();
			void append(const list<T>&);
			void erase(list_iterator<T>);
			void insert_before(list_iterator<T>, const T&);
	};
	template<typename T>
	std::ostream& operator <<(std::ostream&, const list_iterator<T>&);
	template<typename T>
	std::istream& operator >>(std::istream&, list_iterator<T>&);
	template<typename T>
	std::ostream& operator <<(std::ostream&, const list<T>&);
	template<typename T>
	std::istream& operator >>(std::istream&, list<T>&);
}

#include "list.cpp"
#endif
